﻿using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using SangaiTech.Abstractions;
using SangaiTech.Mvc.Areas.api.Controllers;
using SimpleInjector;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Http;
using System.Web.Http.Results;
using TechTalk.SpecFlow;

namespace SangaiTech.Mvc.Specs
{
    [Binding]
    public class EmployeeApiFeatureSteps
    {
        EmployeeController _employeeController;
        private int _numberOfActiveEmployeesToFake;
        private int _numberOfRetiredEmployees;
        
        #region Constructor with mockings
        public EmployeeApiFeatureSteps()
        {
            var  mockEmployeeRepository=new Mock<IEmployeeRepository>();
            mockEmployeeRepository.Setup(r => r.All()).Returns(MockEmployees);

            _employeeController = new EmployeeController(mockEmployeeRepository.Object);
        }
        
        public IQueryable<Employee> MockEmployees()
        {
            var employees = new List<Employee>();
            for (int i=1; i <= _numberOfActiveEmployeesToFake; i++)
            {
                employees.Add(new Employee { EmployeeId = i, FirstName = "EMP" + i, LastName = "TEST" + i, IsRetired = false });
            };
            for (int i=1; i <= _numberOfRetiredEmployees; i++)
            {
                employees.Add(new Employee { EmployeeId = i, FirstName = "EMP" + i, LastName = "TEST" + i, IsRetired = true, RetirementDate = DateTime.Today });
            }
            return employees.AsQueryable();
        }
        #endregion

        #region Get Active Employees Specs

        [Given(@"I have ""(.*)"" active employees records")]
        public void GivenIHaveActiveEmployeesRecords(int numberOfActiveEmployeesToFake)
        {
            _numberOfActiveEmployeesToFake = numberOfActiveEmployeesToFake;
        }

        [Given(@"I have ""(.*)"" retired employees")]
        public void GivenIHaveRetiredEmployees(int numberOfRetiredEmployeesToFake)
        {
            _numberOfRetiredEmployees = numberOfRetiredEmployeesToFake;
        }

        IHttpActionResult _result;
        [When(@"I get all employees from EmployeesApi")]
        public void WhenIGetAllEmployeesFromEmployeesApi()
        {
            _result = _employeeController.Get();
        }
        [Then(@"the result should be ""(.*)"" employees who are not retired")]
        public void ThenTheResultShouldBeEmployeesWhoAreNotRetired(int expectedNumberOfActiveEmployees)
        {
            var employees = _result as OkNegotiatedContentResult<List<Employee>>;
            Assert.AreEqual(expectedNumberOfActiveEmployees, employees.Content.Count());
        }

        #endregion

        #region Post employee validation specs

        Employee _newEmployee;

        [Given(@"I have an employee attribute ""(.*)"" and value ""(.*)""")]
        public void GivenIHaveAnEmployeeAttributeAndValue(string employeeAttributeName, string attributeValue)
        {
            _newEmployee = new Employee { DepartmentId = 100, LastName = "TEST", FirstName = "XX" };
            if (employeeAttributeName == "FirstName")
                _newEmployee.FirstName = attributeValue;
        }

        [When(@"I post the employee to EmployeesApi")]
        public void WhenIPostTheEmployeeToEmployeesApi()
        {
           _result =  _employeeController.Post(_newEmployee);
        }

        [Then(@"the employeesApi should throw an exception with message ""(.*)""")]
        public void ThenTheEmployeesApiShouldThrowAnExceptionWithMessage(string expectedExceptionMessage)
        {
            var badRequestException = _result as System.Web.Http.Results.BadRequestErrorMessageResult;
            Assert.IsNotNull(badRequestException, "expected validation not happening");
            Assert.AreEqual(expectedExceptionMessage.ToLower(), badRequestException.Message.ToLower(), "expected validation message not match the actual validation");
        }
        #endregion
    }
}
